package com.csaba.connector.otp;

import java.io.StringReader;
import java.util.Arrays;
import java.util.Calendar;
import java.util.logging.Logger;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import com.csaba.connector.I18NServiceException;
import com.csaba.connector.ServiceException;
import com.csaba.connector.model.Session;
import com.csaba.connector.otp.model.OTPBank;
import com.csaba.connector.otp.model.OTPHistoryItem;
import com.csaba.connector.otp.model.OTPRequestFactory;
import com.csaba.connector.otp.model.OTPSession;
import com.csaba.connector.otp.parser.AccountHistoryParser;
import com.csaba.connector.service.AbstractAccountHistoryService;
import com.csaba.util.LoggerHelper;

public class OTPAccountHistoryService extends AbstractAccountHistoryService
{
	public static final int HISTORY_TIME_LIMIT = 92;

	private final static Logger logger = LoggerHelper.getDefaultLogger();

	@Override
	public void execute( final Session session ) throws ServiceException
	{
		if ( !( session instanceof OTPSession ) )
			throw new ServiceException("Incompatible session " + OTPBank.class + " != " + session.getClass().getName());

		if ( account == null || !OTPBank.getInstance().equals(account.getBank()) || from == null || to == null )
			throw new ServiceException("Service is not initialized yet correctly.");

		//time range is limited to 3 month (92 days)... 
		final Calendar timeLimit = Calendar.getInstance();
		timeLimit.add(Calendar.DATE, -HISTORY_TIME_LIMIT);

		if ( timeLimit.getTime().after(from) )
		{
			throw new I18NServiceException(OTPBank.getInstance(), "msg.historyForm3Month");
		}

		final OTPSession otp = (OTPSession) session;

		OTPAccountService.selectAccount(account, otp);

		final Calendar from = Calendar.getInstance();
		final Calendar to = Calendar.getInstance();
		from.setTime(this.from);
		to.setTime(this.to);
		//post input request
		final NameValuePair[] inputData = new NameValuePair[] {// 
		new BasicNameValuePair("muveletStatusz", "bevitel"),//
				new BasicNameValuePair("kliensTranzakcioId", ""), //
				new BasicNameValuePair("induloDatum.ev", String.valueOf(from.get(Calendar.YEAR))),//
				new BasicNameValuePair("induloDatum.honap", String.valueOf(from.get(Calendar.MONTH) + 1)),//
				new BasicNameValuePair("induloDatum.nap", String.valueOf(from.get(Calendar.DATE))),//
				new BasicNameValuePair("zaroDatum.ev", String.valueOf(to.get(Calendar.YEAR))),//
				new BasicNameValuePair("zaroDatum.honap", String.valueOf(to.get(Calendar.MONTH) + 1)),//
				new BasicNameValuePair("zaroDatum.nap", String.valueOf(to.get(Calendar.DATE))),//
				new BasicNameValuePair("forgalomFeltetel", "0"),//both credit and debit
				new BasicNameValuePair("szamlaszamFeltetel", ""),//
				new BasicNameValuePair("formButtons(elkuld).x", String.valueOf((int) ( Math.random() * 30 ))),//
				new BasicNameValuePair("formButtons(elkuld).y", String.valueOf((int) ( Math.random() * 30 ))), };
		logger.fine("History params: " + Arrays.toString(inputData));

		final String requestResult = otp.doPost(OTPRequestFactory.HOMEBANK_REQUEST_URL_BASE
				+ OTPRequestFactory.REQUEST_GET_ACCOUNT_HISTORY, inputData);
		otp.debugFile("accountHistoryRequestResult", requestResult);

		if ( AccountHistoryParser.isFailed(requestResult) )
		{
			//no need to parse error message, as no useful information is returned
			throw new I18NServiceException(OTPBank.getInstance(), "msg.historyError", (Throwable) null, account);
		}

		//poll response
		final NameValuePair[] pollData = new NameValuePair[] {// 
		new BasicNameValuePair("muveletStatusz", "varakozas"),//
				new BasicNameValuePair("kliensTranzakcioId", String.valueOf(otp.getOperationCounter())), };

		int pollCount = 0;
		String finalResult = null;
		for ( ; finalResult == null && pollCount < TransactionPolling.POLL_LIMIT; pollCount++ )
		{
			try
			{
				Thread.sleep(TransactionPolling.POLL_PERIOD);
			}
			catch ( final InterruptedException ex )
			{
				logger.finest("Sleep was interrupted.");
			}

			final String pollResult = otp.doPost(OTPRequestFactory.HOMEBANK_REQUEST_URL_BASE
					+ OTPRequestFactory.REQUEST_GET_ACCOUNT_HISTORY, pollData);
			otp.debugFile("accountHistoryPollResult", pollResult);

			if ( !pollResult.contains("varakozas_animacio") )
			{
				finalResult = pollResult;
			}
		}

		if ( finalResult == null )
		{
			throw new I18NServiceException(OTPBank.getInstance(), "msg.historyTimeout", (Throwable) null,
					( TransactionPolling.POLL_LIMIT * TransactionPolling.POLL_PERIOD / 1000 ), account);
		}

		//parse result
		if ( AccountHistoryParser.isParsable(finalResult) )
		{
			try
			{
				historyItems = AccountHistoryParser.parseAccountHistoryList(new StringReader(finalResult), account);
			}
			catch ( final Exception e )
			{
				throw new I18NServiceException(OTPBank.getInstance(), "msg.historyProcessingError", e);
			}
		}
		else
		{
			//check if there is any error
			if ( AccountHistoryParser.isFailed(finalResult) )
			{
				//no need to for parsing error as no useful details are returned.
				throw new I18NServiceException(OTPBank.getInstance(), "msg.historyFailure", (Throwable) null, account);
			}
			else
			{
				historyItems = new OTPHistoryItem[0];
			}
		}

	}
	//account select: https%3A//www.otpbankdirekt.hu/homebank/do/bankszamla/bankszamlaMuvelet%3Bjsessionid%3DL8qJsCZcrSJ2m0gQf3PysyDjGNZ1gdTK9TgjqDZhLTdqP8jJYRZV%211577071256%21NONE%3FszamlaSzamIndex%3D0

	//input URI: https%3A//www.otpbankdirekt.hu/homebank/do/bankszamla/szamlatortenet%3Bjsessionid%3DL8ypbSGy9P3rz7v8GVrhhtLhsRLBhncQLLjXJQRtNtCg4Gx5LZpS%211580759978%211577071256

	//request: https%3A//www.otpbankdirekt.hu/homebank/do/bankszamla/szamlatortenet%3Bjsessionid%3DL8ypbSGy9P3rz7v8GVrhhtLhsRLBhncQLLjXJQRtNtCg4Gx5LZpS%211580759978%211577071256
	/*
	<tdPostElements>
		<tdPostElement name="muveletStatusz">bevitel</tdPostElement>
		<tdPostElement name="kliensTranzakcioId"></tdPostElement>
		<tdPostElement name="induloDatum.ev">2008</tdPostElement>
		<tdPostElement name="induloDatum.honap">6</tdPostElement>
		<tdPostElement name="induloDatum.nap">1</tdPostElement>
		<tdPostElement name="zaroDatum.ev">2008</tdPostElement>
		<tdPostElement name="zaroDatum.honap">7</tdPostElement>
		<tdPostElement name="zaroDatum.nap">15</tdPostElement>
		<tdPostElement name="forgalomFeltetel">0</tdPostElement> [2=credit, 1=debit, 0=both]
		<tdPostElement name="szamlaszamFeltetel"></tdPostElement> [partner accout filtering]
		<tdPostElement name="formButtons%28elkuld%29.x">30</tdPostElement>
		<tdPostElement name="formButtons%28elkuld%29.y">9</tdPostElement>
	</tdPostElements>

	 */

	//https%3A//www.otpbankdirekt.hu/homebank/do/bankszamla/szamlatortenet%3Bjsessionid%3DL8ypbSGy9P3rz7v8GVrhhtLhsRLBhncQLLjXJQRtNtCg4Gx5LZpS%211580759978%211577071256
	/*
	<tdPostElements>
		<tdPostElement name="kliensTranzakcioId">5</tdPostElement>
		<tdPostElement name="muveletStatusz">varakozas</tdPostElement>
	</tdPostElements>

	 */

}
